package com.ad.nbi.epirpsystem.server;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Random;

import org.omg.CORBA.IntHolder;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNotification.EventHeader;
import org.omg.CosNotification.EventType;
import org.omg.CosNotification.FixedEventHeader;
import org.omg.CosNotification.Priority;
import org.omg.CosNotification.Property;
import org.omg.CosNotification.StructuredEvent;
import org.omg.CosNotifyChannelAdmin.ClientType;
import org.omg.CosNotifyChannelAdmin.EventChannel;
import org.omg.CosNotifyChannelAdmin.EventChannelFactory;
import org.omg.CosNotifyChannelAdmin.EventChannelFactoryHelper;
import org.omg.CosNotifyChannelAdmin.StructuredProxyPushConsumer;
import org.omg.CosNotifyChannelAdmin.StructuredProxyPushConsumerHelper;
import org.omg.CosNotifyChannelAdmin.SupplierAdmin;
import org.omg.CosNotifyComm.StructuredPushSupplierHelper;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.Servant;

import AlarmIRPNotifications.NotifyNewAlarm;
import AlarmIRPNotifications.NotifyNewAlarmHelper;
import CosNotification.DefaultPriority;

import com.ad.nbi.alarmirpnotifications.NotifyNewAlarmServerImpl;
import com.ad.nbi.alarmirpnotifications.Server;
import com.ad.nbi.alarmirpnotifications.StructuredPushSupplierImpl;

public class NtfyServer extends Thread {
	public static Map<String, String> pushiors = new HashMap<String, String>();
	private org.omg.CORBA.ORB orb;
	private StructuredProxyPushConsumer structuredProxyPushConsumer;

	public NtfyServer(String[] args, Servant interfImpl, String iorkey) {
		Properties props = System.getProperties();
		props.setProperty("org.omg.CORBA.ORBClass", "org.jacorb.orb.ORB");
		props.setProperty("org.omg.CORBA.ORBSingletonClass",
				"org.jacorb.orb.ORBSingleton");
		props.setProperty("ORBInitRef.NotificationService",
				"corbaloc::192.168.0.57:30001/NotificationService");
		orb = org.omg.CORBA.ORB.init(args, props);

		try

		{

			org.omg.PortableServer.POA rootPoa =

			org.omg.PortableServer.POAHelper.narrow(

			orb.resolve_initial_references("RootPOA"));

			rootPoa.the_POAManager().activate();

			EventChannelFactory eventChannelFactory = EventChannelFactoryHelper
					.narrow(orb
							.resolve_initial_references("NotificationService"));

			Property[] initialQos = new Property[0];
			Property[] initialAdmin = new Property[0];
			EventChannel eventChannel = (EventChannel) eventChannelFactory
					.create_channel(initialQos, initialAdmin, new IntHolder());

			StructuredPushSupplierImpl pushSupplierImpl = new StructuredPushSupplierImpl();
			SupplierAdmin supplierAdmin = (SupplierAdmin) eventChannel
					.default_supplier_admin();
			this.structuredProxyPushConsumer = StructuredProxyPushConsumerHelper
					.narrow(supplierAdmin.obtain_notification_push_consumer(
							ClientType.STRUCTURED_EVENT, new IntHolder()));

			org.omg.CORBA.Object pushSupplierObject = rootPoa
					.servant_to_reference(pushSupplierImpl);
			structuredProxyPushConsumer
					.connect_structured_push_supplier(StructuredPushSupplierHelper
							.narrow(rootPoa
									.servant_to_reference(pushSupplierImpl)));
			if (args.length == 1) {
				PrintWriter ps = new PrintWriter(

				new FileOutputStream(

				new File(args[0])));
				String IOR = orb.object_to_string(eventChannel);
				System.out.println("IOR:" + IOR);
				ps.println(IOR);
				ps.close();
				pushiors.put(iorkey, IOR);

				Thread t = new Thread(new Server(orb,
						structuredProxyPushConsumer));
				t.start();

				System.out.println("MyService is running and waiting......");
				orb.run();
			} else

			{

				// register with the naming service

				NamingContextExt nc =

				NamingContextExtHelper.narrow(

				orb.resolve_initial_references("NameService"));

			}

		}

		catch (Exception e)

		{

			e.printStackTrace();

		}

	}

	@Override
	public void run() {
		int i = 0;

		try {
			this.structuredProxyPushConsumer.offer_change(new EventType[] {
					new EventType("NewsBC", "Sports"),
					new EventType("NewsBC", "Economy"),
					new EventType("NewsBC", "Entertainment") },
					new EventType[0]);

			while (!Thread.interrupted()) {
				EventType eventType = new EventType();
				eventType.domain_name = "NewsBC";
				eventType.type_name = (i % 3 == 0) ? "Sports"
						: ((i % 3 == 1) ? "Economy" : "Entertainment");

				EventHeader eventHeader = new EventHeader();

				eventHeader.fixed_header = new FixedEventHeader();
				eventHeader.fixed_header.event_type = eventType;
				eventHeader.fixed_header.event_name = "Event No. " + i++;

				eventHeader.variable_header = new Property[1];
				eventHeader.variable_header[0] = new Property();
				eventHeader.variable_header[0].name = Priority.value;
				eventHeader.variable_header[0].value = orb.create_any();
				short priority = (short) (DefaultPriority.value + new Random()
						.nextInt(3));
				eventHeader.variable_header[0].value.insert_short(priority);

				StructuredEvent event = new StructuredEvent();
				event.header = eventHeader;
				event.filterable_data = new Property[0];
				event.remainder_of_body = orb.create_any();

				POA poaRoot = POAHelper.narrow(orb
						.resolve_initial_references("RootPOA"));
				// 激活POA管理器
				poaRoot.the_POAManager().activate();
				// 实例化一个MyServiceServerImpl对象
				NotifyNewAlarmServerImpl serviceImpl = new NotifyNewAlarmServerImpl();

				// 从servant获得对象引用
				org.omg.CORBA.Object refObj = poaRoot
						.servant_to_reference(serviceImpl);
				// 获得对象接口引用
				NotifyNewAlarm href = NotifyNewAlarmHelper.narrow(refObj);

				event.remainder_of_body.insert_Object(href);

				try {
					this.structuredProxyPushConsumer
							.push_structured_event(event);
				} catch (org.omg.CosEventComm.Disconnected e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Thread.sleep(3000);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.structuredProxyPushConsumer.disconnect_structured_push_consumer();
		this.orb.shutdown(true);

	}
}
